package strings;

import common.MyLinkList;
import errors.MyWarning;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedList;

/**
 * User: MiF
 * Date: 30.12.11
 * Time: 13:25
 */
public class File {
    private String alias;
    private String after;
    private Boolean dynamic;
    private boolean bad;
    private MyLinkList<Str> strs;

    public File(java.io.File file) {
        this.alias = file.getName().toUpperCase().replaceAll("\\W", "_");
        this.after = "";
        this.dynamic = true;
        this.bad=false;
        this.strs = new MyLinkList<Str>();

        // Начинаем чтение
        try {
            BufferedReader reader;
            reader = new BufferedReader(new FileReader(file.getAbsolutePath()));
            String inpLine = reader.readLine();
            if (inpLine == null)
                return;
            // Убираем двойные пробелы и пробелы около знака =
            inpLine = inpLine.trim();
            while (inpLine.contains("  "))
                inpLine = inpLine.replaceAll("  ", " ");
            while (inpLine.contains(" =") || inpLine.contains("= "))
                inpLine = inpLine.replaceAll(" *= *", "=");

            // Разбиваем первую строку по пробелу и смотрим входные параметры
            String[] fileParams = inpLine.toUpperCase().split(" ");
            for (String fileParam : fileParams) {
                String[] para = fileParam.split("=");
                if (para.length != 2) {
                    MyWarning.add(fileParam, "Нестандартная пара 'КЛЮЧ=ЗНАЧЕНИЕ', они проигнорированы (файл: "+file.getAbsolutePath()+")");
                    continue;
                }
                if (para[0].toLowerCase().equals("alias")) {
                    String t = para[1].replaceAll("\\W", "_");
                    if (!para[1].equals(t))
                        MyWarning.add(para[1], "Недопустимые символы ключа 'alias' заменены на '_' (подчеркивание) (файл: "+file.getAbsolutePath()+")");
                    this.alias = t;
                } else if (para[0].toLowerCase().equals("after")) {
                    String t = para[1].replaceAll("\\W", "_");
                    if (!para[1].equals(t))
                        MyWarning.add(para[1], "Недопустимые символы ключа 'after' заменены на '_' (подчеркивание) (файл: "+file.getAbsolutePath()+")");
                    this.after = t;
                } else if (para[0].toLowerCase().equals("type")) {
                    if (para[1].toLowerCase().equals("dynamic"))
                        this.dynamic = true;
                    else if (para[1].toLowerCase().equals("static"))
                        this.dynamic = false;
                    else if (para[1].toLowerCase().equals("bad")) {
                        bad=true;
                    } else
                        MyWarning.add(para[1], "Недопустимое значение ключа 'type' (dynamic/static/bad) (файл: "+file.getAbsolutePath()+")");
                } else
                    MyWarning.add(para[0], "Недопустимый ключ '" + para[0] + "' (файл: "+file.getAbsolutePath()+")");
            }

            strs.add(new Str(1,"//*************************************************************************************"));
            strs.add(new Str(2,"//** File:"+file.getAbsolutePath()+"   alias:"+alias+"   after:"+after+"   type:"+(bad?"bad":(dynamic?"dynamic":"static"))+"   "));
            strs.add(new Str(3,"//*************************************************************************************"));

            if(bad)
                return;

            // Читаем строки файла
            int lineNum=3;
            while ((inpLine = reader.readLine()) != null) {
                lineNum++;
                if (!dynamic) {
                    strs.add(Str.getStaticStr(lineNum,inpLine));
                    continue;
                }

                // Разбиваем на подстроки через ';'
                MyLinkList<String> tStrsSplitRow=Str.split(new Str(lineNum,inpLine), inpLine,";",false,true,false);
                for(String tStrSplitRow : tStrsSplitRow)
                    strs.add(new Str(lineNum,tStrSplitRow));
            }

        } catch (FileNotFoundException e) {
            System.out.println("File not found: '" + file.getAbsolutePath() + "'");
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println("File IO error: '" + file.getAbsolutePath() + "'");
            e.printStackTrace();
        }
    }

    public boolean isBad() {
        return bad;
    }

    public LinkedList<Str> getStrBlocks() {
        return strs;
    }

    /* -----------------------===============================----------------------- */
    /* CLASS CLASS CLASS CLASS CLASS CLASS CLASS CLASS CLASS CLASS CLASS CLASS CLASS */
    /* -----------------------===============================----------------------- */

    private static LinkedList<File> parsedFiles = new LinkedList<File>();

    public static LinkedList<Str> getStrings(String basePath){
        // Поиск в папках и подпапках
        java.io.File folder = new java.io.File(basePath);
        findFiles(folder);

        // ToDo: дописать порядок
        LinkedList<Str> strs = new LinkedList<Str>();
        for (File parseFile : parsedFiles)
            strs.addAll(parseFile.getStrBlocks());

        return strs;
    }

    private static void findFiles(java.io.File folder) {
        for (java.io.File f : folder.listFiles())
            if (f.isFile()) {
                if (f.getName().toLowerCase().endsWith(".mif")) {
                    File parseFile = new File(f);
                    if (!parseFile.isBad())
                        parsedFiles.add(parseFile);
                }
            } else if (f.isDirectory())
                findFiles(f.getAbsoluteFile());
    }
}
